package cn.android666.audiorecorder.permission

import android.content.pm.PackageManager
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.app.ActivityCompat
import androidx.fragment.app.FragmentActivity
import timber.log.Timber

/**
 * 普通权限的申请工具，比如摄像头权限、定位权限等（区别于流量统计权限、Android11文件管理权限等的一些特殊权限）。
 * 使用步骤为：1、调用setRequestPermissions()来设置需要的权限。2、调用registerForActivityResult()注册结果监听器。3、调用requestPermissions()请求权限并接收结果
 */
class NormalPermissionUtil {

    companion object {

        /** 正常权限结果的启动器（比如写SD卡权限、读取电话状态权限等） */
        private lateinit var launcher: ActivityResultLauncher<Array<String>>
        private lateinit var resultCallback: () -> Unit

        // 声明需要申请的权限和对应的权限名称
        private lateinit var requestPermissions: Map<String, String>

        /**
         * 设置需要请求的权限，并且要求给每个权限起一个中文名字，以方便进行提示，示例如下：
         * mapOf(Manifest.permission.CAMERA to "摄像头", Manifest.permission.ACCESS_FINE_LOCATION to "定位")
         */
        fun setRequestPermissions(requestPermissions: Map<String, String>) {
            Companion.requestPermissions = requestPermissions
        }

        /**
         * 动态申请应用中需要的权限，权限在requestPermissions变量中进行声明。当获得所有权限时回调给hasAllPermission函数。
         * 注：在onCreate函数中调用
         * 需求：
         * androidx.activity，1.2.0 或更高版本。
         * androidx.fragment，1.3.0 或更高版本。
         * 示例如下：
         * implementation "androidx.activity:activity-ktx:1.3.0"
         * implementation "androidx.fragment:fragment-ktx:1.3.6"
         */
        fun registerForActivityResult(activity: FragmentActivity) {
            launcher = activity.registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { result: Map<String, Boolean> ->
                Timber.i("普通权限申请结果：$result")
                val deniedPermissions = mutableListOf<String>()     // 被拒绝的权限
                val neverTipPermissions = mutableListOf<String>()   // 被设置不再提示的权限
                for ((permission, granted) in result) {
                    if (!granted) {
                        if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)) {
                            // 权限被拒绝
                            deniedPermissions.add(permission)
                        } else {
                            // 权限被设置为不再提示
                            neverTipPermissions.add(permission)
                        }
                    }
                }

                if (deniedPermissions.isEmpty() && neverTipPermissions.isEmpty()) {
                    Timber.i("所有普通权限都允许了，恭喜！")
                    resultCallback()
                } else {
                    showTipDialog(activity, deniedPermissions, neverTipPermissions)
                }
            }
        }


        /** 请求普通权限  */
        fun requestPermissions(activity: FragmentActivity, hasAllPermission: () -> Unit) {
            resultCallback = hasAllPermission
            val permissions = requestPermissions.keys.toTypedArray()
            val noGrantedPermission = mutableListOf<String>()
            for (permission in permissions) {
                if (ActivityCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
                    noGrantedPermission.add(permission)
                }
            }
            if (noGrantedPermission.isEmpty()) {
                hasAllPermission()
            } else {
                launcher.launch(noGrantedPermission.toTypedArray())
            }
        }

        private fun showTipDialog(activity: FragmentActivity, deniedPermissions: MutableList<String>, neverTipPermissions: MutableList<String>) {
            val desc: String
            val permissions: MutableList<String>

            if (deniedPermissions.isNotEmpty()) {
                // 权限被拒绝
                permissions = deniedPermissions
                desc = "本App需要使用%s权限，请允许此权限，否则无法使用本app"
            } else {
                // 权限被设置为不再提示
                permissions = neverTipPermissions
                desc = "本App需要使用%s权限，您需要到设置中打开此权限，否则无法使用本app"
            }

            val allPermissionDesc = StringBuilder()
            permissions.forEachIndexed { index, permission ->
                if (index > 0) allPermissionDesc.append("、")
                allPermissionDesc.append(requestPermissions[permission])
            }

            val message = String.format(desc, allPermissionDesc)
            Timber.w(message)

            UiUtil.showOneButtonDialog(activity, message) {
                requestPermissions(activity, resultCallback)
            }
        }

    }
}